/**
 * compressor module
 *
 * @author strlst <e11907086@student.tuwien.ac.at>
 * @date 2020-11-05
 * @brief contains compress function that does all the work
 * @details none
 */

#include "compress.h"

int compress(char *infilepath, char *outfilepath) {
    /* initialize file pointer */
    FILE *fi_p;
    FILE *fo_p;

    /* open infile and check for errors */
    if ((fi_p = fopen(infilepath, "r")) == NULL) {
        fprintf(stderr, "osue-zip: error opening specified file(s) for reading: %s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    /* open outfile and check for errors */
    if ((fo_p = fopen(outfilepath, "a")) == NULL) {
        fprintf(stderr, "osue-zip: error opening specified file(s) for writing: %s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    /* initialization */
    char c, last_c;
    size_t count = 0;
    size_t total_in = 0, total_out = 0;

    /* to be consistent with the logic of the loop below, initialize once */
    last_c = (c = fgetc(fi_p));
    do {
        /* check if c has changed from last_c */
        if (c != last_c) {
            fprintf(fo_p, "%c%li", last_c, count);

            /* increment total_in */
            total_in += count;

            /* add 1 for c as well as digit count of count */
            total_out += 1 + (size_t)floor(log10(count) + 1);

            /* reset counter */
            count = 0;
        }
        /* increment and save */
        last_c = c;
        c = fgetc(fi_p);
        ++count;
    /* query for EOF and get new c */
    } while (last_c != EOF);

    /* print auxiliary information to stderr */
    fprintf(fo_p, "\n");
    fprintf(fo_p, "Read:    %li characters\n", total_in);
    fprintf(fo_p, "Written: %li characters\n", total_out);
    fprintf(fo_p, "Compression ratio: %.2f%%\n", (float)total_out / (float)total_in * 100.);

    if (fclose(fi_p) < 0 || fclose(fo_p) < 0) {
        fprintf(stderr, "osue-zip: error closing specified file: %s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
